package com.shuai.chatroom.controller;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.shuai.chatroom.common.AppConstant;
import com.shuai.chatroom.common.HttpResult;
import com.shuai.chatroom.config.UserOnLineStateManager;
import com.shuai.chatroom.entity.FriendApplyInfo;
import com.shuai.chatroom.entity.FriendInfo;
import com.shuai.chatroom.entity.UserInfo;
import com.shuai.chatroom.entity.vo.FriendApplyInfoVO;
import com.shuai.chatroom.exception.ControllerException;
import com.shuai.chatroom.service.FriendApplyService;
import com.shuai.chatroom.service.FriendService;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.time.LocalDateTime;

@RestController
@RequestMapping("/apply")
public class FriendApplyController {
    @Resource
    private FriendApplyService friendApplyService;

    @Resource
    private UserOnLineStateManager userOnLineStateManager;

    @Resource
    private ObjectMapper objectMapper;

    @Resource
    private FriendService friendService;


    @RequestMapping("/add")
    public HttpResult addApply(FriendApplyInfo friendApplyInfo, HttpServletRequest request) throws ControllerException, JsonProcessingException {
        HttpSession session = request.getSession(false);
        UserInfo userInfo;
        if (session == null
                || (userInfo = (UserInfo) session.getAttribute(AppConstant.USER_SESSION_KEY)) == null
                || userInfo.getUId() == null
                || !StringUtils.hasLength(friendApplyInfo.getApplyReason())
                || friendApplyInfo.getToUId() == null) {
            throw new ControllerException("非法参数！");
        }
        //根据fromUId和toUId判断时候已经添加过了
        if (friendApplyService.isSend(userInfo.getUId(), friendApplyInfo.getToUId())) {
            return HttpResult.fail("已经添加过了，请等待对方同意！");
        }
        friendApplyInfo.setFromUId(userInfo.getUId());
        //将验证信息添加到数据库表中
        friendApplyService.addApply(friendApplyInfo);   //返回了自增主键
        //判断用户是否在线，如果在线的话，直接通过websocket将验证消息发送给用户
        WebSocketSession toUserSession = userOnLineStateManager.getUserSession(friendApplyInfo.getToUId());
        if (toUserSession != null) {
            FriendApplyInfoVO applyVO = friendApplyService.getApplyVO(friendApplyInfo.getApplyId());    //得到了申请人的用户名和头像
            applyVO.setType(AppConstant.MESSAGE_TYPE_APPLY);    //设置消息类型为验证消息
            applyVO.setSendTime(LocalDateTime.now());   //设置申请的时间 --响应
            applyVO.setApplyReason(friendApplyInfo.getApplyReason());  //设置申请原因
            applyVO.setApplyId(friendApplyInfo.getApplyId());       //设置申请消息的id
            applyVO.setFromUId(friendApplyInfo.getFromUId());       //设置申请消息的发出人编号
            try {
                toUserSession.sendMessage(new TextMessage(objectMapper.writeValueAsString(applyVO)));
            } catch (IOException e) {
                throw new ControllerException("发送失败，请稍后重试！");
            }
        }
        return HttpResult.success(200);
    }


    @RequestMapping("/get_applies")
    public HttpResult getApplies(HttpServletRequest request) throws ControllerException {
        HttpSession session = request.getSession(false);
        UserInfo userInfo;
        if (session == null || (userInfo = (UserInfo) session.getAttribute(AppConstant.USER_SESSION_KEY)) == null || userInfo.getUId() == null) {
            throw new ControllerException("非法参数！");
        }
        return HttpResult.success(friendApplyService.getApplies(userInfo.getUId()));
    }

    @RequestMapping("/agree")
    public HttpResult agreeReq(Integer applyId, HttpServletRequest request) throws ControllerException {
        UserInfo userInfo = (UserInfo) request.getSession(false).getAttribute(AppConstant.USER_SESSION_KEY);
        if (userInfo == null || userInfo.getUId() == null) {
            throw new ControllerException("非法请求");
        }
        if (applyId == null) {
            throw new ControllerException("非法参数");
        }
        //TODO: 删除验证信息,新增好友关系
        FriendApplyInfoVO applyVO = friendApplyService.getApplyVO(applyId);
        if (applyVO != null) {
            //删除验证信息
            friendApplyService.delApply(userInfo.getUId(), applyId);
            //新增好友关系
            FriendInfo friendInfo = new FriendInfo();
            friendInfo.setUId(userInfo.getUId());   //接收者
            friendInfo.setFId(applyVO.getFromUId());//发起者
            friendService.addFriendRelationShip(friendInfo);
            return HttpResult.success(200);
        } else {
            return HttpResult.fail("您无权操作不属于您的验证消息！");
        }
    }


    @RequestMapping("/refuse")
    public HttpResult refuseReq(Integer applyId, HttpServletRequest request) throws ControllerException {
        UserInfo userInfo = (UserInfo) request.getSession(false).getAttribute(AppConstant.USER_SESSION_KEY);
        if (userInfo == null || userInfo.getUId() == null) {
            throw new ControllerException("非法请求");
        }
        if (applyId == null) {
            throw new ControllerException("非法参数");
        }
        boolean isSuccess = friendApplyService.delApply(userInfo.getUId(), applyId) > 0;
        if (!isSuccess) {
            return HttpResult.fail("您无权操作不属于您的验证消息！");
        }
        return HttpResult.success(200);
    }
}
